package org.huzhp.gateway.service;

import cn.hutool.core.util.HashUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;

/**
 * @Description: 调用日志
 * @Author: huzp
 * @CreateDate: 2020/4/13 12:48
 * @Version: 1.0
 */

public abstract class AbstractAuditLogService {

    protected final static Logger logger = LoggerFactory.getLogger(AbstractAuditLogService.class);

    protected SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private ExecutorService executor;

    public AbstractAuditLogService(ExecutorService executor) {
        this.executor = executor;
    }

    public void logError(Map<String, Object> error, ServerHttpRequest request) {
        String userAgent = request.getHeaders().getFirst("User-Agent");

        Map<String, Object> param = new HashMap<>();
        UserAgent ua = UserAgentUtil.parse(userAgent);
        param.put("logRoute", HashUtil.oneByOneHash(request.getRemoteAddress().toString() + userAgent));
        param.put("logRequestId", request.getId());
        param.put("logTime", error.get("timestamp"));
        param.put("logIp", request.getRemoteAddress().getAddress().getHostAddress());
        param.put("logSystem", ua.getPlatform().toString());
        param.put("logBrower", ua.getBrowser().toString());
        param.put("logVersion", ua.getVersion());
        param.put("logMobile", ua.isMobile() ? 1 : 0);
        param.put("logUrl", request.getURI().toString());
        param.put("logMethod", request.getMethod().toString());
        param.put("logStatus", error.get("status"));
        param.put("logMessage", error.get("message"));
        param.put("logTook", error.get("executeTime"));
        executor.submit(() -> auditLog(param));
    }

    public abstract void auditLog(Map<String, Object> message);

}
